#include <iostream>
#include <string>
#include <vector>
#include "gismap_globalconfig.h"
#include "c2cplatform/library/string/string_helper.h"


using namespace erp::gis::ao;
using namespace c2cplatform::library::string;

const std::string DEFAULT_SOSOAPI_URL   = "http://api.map.qq.com/?qt=poi&wd=(input_addr)&output=json&fr=mapapi";
const std::string DEFAULT_SOSO2API_URL  = "http://api.map.qq.com/geoc/?addr=(input_addr)&output=jsonp&fr=webapi";
const std::string DEFAULT_GOOGLEAPI_URL = "http://maps.googleapis.com/maps/api/geocode/json?address=(input_addr)&sensor=false&language=zh-CN";
const std::string DEFAULT_BAIDUAPI_URL  = "http://api.map.baidu.com/geocoder?address=(input_addr)&output=json&city=(input_city)&src=Icson|IcsonGIS";
const std::string DEFAULT_ALIYUNAPI_URL = "http://gc.ditu.aliyun.com/geocoding?a=(input_addr)";
const std::string DEFAULT_GAODEAPI_URL  = "http://api.amap.com:9090/geocode/simple?resType=json&encode=utf8&address=(input_addr)";


CGisMapConfigInfo CGisMapGlobalConfig::m_oSosoConfig;
CGisMapConfigInfo CGisMapGlobalConfig::m_oSoso2Config;
CGisMapConfigInfo CGisMapGlobalConfig::m_oBaiduConfig;
CGisMapConfigInfo CGisMapGlobalConfig::m_oGoogleConfig;
CGisMapConfigInfo CGisMapGlobalConfig::m_oAliyunConfig;
CGisMapConfigInfo CGisMapGlobalConfig::m_oGaodeConfig;
uint32_t CGisMapGlobalConfig::m_dwSwitchProxyThreshold;


int CGisMapGlobalConfig::ParseProxy(const std::string& strProxyList, std::vector<CProxy>& vecProxy)
{
	if (strProxyList.empty())
	{
		return 0;
	}

	std::vector<std::string> vecProxyStr;
	SplitStringIntoVector(strProxyList.c_str(), ",", vecProxyStr);
	if (vecProxyStr.empty())
	{
		return 1;
	}

	std::vector<std::string>::const_iterator iter = vecProxyStr.begin();
	std::vector<std::string>::const_iterator iterEnd = vecProxyStr.end();
	for (; iter != iterEnd; iter++)
	{
		std::vector<std::string> vecProxyInfo;
		SplitStringIntoVector((*iter).c_str(), ":", vecProxyInfo);
		if (vecProxyInfo.empty() || vecProxyInfo.size() != 2)
		{
			return 1;
		}
		
		const std::string& strProxy = vecProxyInfo[0];
		uint32_t dwProxyPort        = strtoul(vecProxyInfo[1].c_str(), 0, 10);
		
		CProxy oProxy(dwProxyPort, strProxy);
		vecProxy.push_back(oProxy);
	}

	return 0;
}

int CGisMapGlobalConfig::SetConfig(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList,
		CGisMapConfigInfo& oGisMapConfigInfo)
{
	std::vector<CProxy> vecProxy;
	int iRet = ParseProxy(strProxyList, vecProxy);
	if (iRet != 0)
	{
		return iRet;
	}

	oGisMapConfigInfo.Init(bNeedCheck, dwTimeout, strUrl, vecProxy);
	return 0;
}

void SwitchProxy(CGisMapConfigInfo& oGisMapConfigInfo)
{
	const CProxy& oCurrentProxy = oGisMapConfigInfo.GetCurrentProxy();
	const std::vector<CProxy>& vecProxyPool = oGisMapConfigInfo.GetProxy();
	if (vecProxyPool.empty())
	{
		return;
	}

	std::vector<CProxy>::const_iterator iter    = vecProxyPool.begin();
	std::vector<CProxy>::const_iterator iterEnd = vecProxyPool.end();
	for (; iter != iterEnd; iter++)
	{
		if (iter->GetProxy()     == oCurrentProxy.GetProxy() &&
			iter->GetProxyPort() == oCurrentProxy.GetProxyPort())
		{
			break;
		}
	}

	CProxy oProxy4Current = vecProxyPool[0];
	if (iter != iterEnd)
	{
		oProxy4Current = *iter;
	}

	oGisMapConfigInfo.SetCurrentProxy(oProxy4Current);
}

uint32_t CGisMapGlobalConfig::GetSwitchProxyThreshold()
{
	return m_dwSwitchProxyThreshold;
}

void CGisMapGlobalConfig::SetSwitchProxyThreshold(uint32_t dwSwitchProxyThreshold)
{
	m_dwSwitchProxyThreshold = dwSwitchProxyThreshold;
}

int CGisMapGlobalConfig::SetSosoConfig(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList)
{
	return SetConfig(bNeedCheck, dwTimeout, strUrl, strProxyList, m_oSosoConfig);
}
void CGisMapGlobalConfig::SwitchSosoProxy()
{
	SwitchProxy(m_oSosoConfig);
}

int CGisMapGlobalConfig::SetSoso2Config(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList)
{
	return SetConfig(bNeedCheck, dwTimeout, strUrl, strProxyList, m_oSoso2Config);
}
void CGisMapGlobalConfig::SwitchSoso2Proxy()
{
	SwitchProxy(m_oSosoConfig);
}

int CGisMapGlobalConfig::SetBaiduConfig(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList)
{
	return SetConfig(bNeedCheck, dwTimeout, strUrl, strProxyList, m_oBaiduConfig);
}

void CGisMapGlobalConfig::SwitchBaiduProxy()
{
	SwitchProxy(m_oBaiduConfig);
}

int CGisMapGlobalConfig::SetGoogleConfig(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList)
{
	return SetConfig(bNeedCheck, dwTimeout, strUrl, strProxyList, m_oGoogleConfig);
}

void CGisMapGlobalConfig::SwitchGoogleProxy()
{
	SwitchProxy(m_oGoogleConfig);
}

int CGisMapGlobalConfig::SetAliyunConfig(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList)
{
	return SetConfig(bNeedCheck, dwTimeout, strUrl, strProxyList, m_oAliyunConfig);
}

void CGisMapGlobalConfig::SwitchAliyunProxy()
{
	SwitchProxy(m_oAliyunConfig);
}

int CGisMapGlobalConfig::SetGaodeConfig(
		bool bNeedCheck,
		uint32_t dwTimeout,
		const std::string& strUrl,
		const std::string& strProxyList)
{
	return SetConfig(bNeedCheck, dwTimeout, strUrl, strProxyList, m_oGaodeConfig);
}

void CGisMapGlobalConfig::SwitchGaodeProxy()
{
	SwitchProxy(m_oGaodeConfig);
}

uint32_t CGisMapGlobalConfig::GetSosoTimeout()
{
	return m_oSosoConfig.GetTimeout();
}
uint32_t CGisMapGlobalConfig::GetSosoProxyPort()
{
	return m_oSosoConfig.GetCurrentProxy().GetProxyPort();
}
bool CGisMapGlobalConfig::GetSosoCheckDataSwitch()
{
	return m_oSosoConfig.IsNeedCheckData();
}
const  std::string& CGisMapGlobalConfig::GetSosoUrl()
{
	if (m_oSosoConfig.GetUrl().empty())
	{
		return DEFAULT_SOSOAPI_URL;
	}
	else
	{
		return m_oSosoConfig.GetUrl();
	}
}
const std::string& CGisMapGlobalConfig::GetSosoProxy()
{
	return m_oSosoConfig.GetCurrentProxy().GetProxy();
}

uint32_t CGisMapGlobalConfig::GetSoso2Timeout()
{
	return m_oSoso2Config.GetTimeout();
}
uint32_t CGisMapGlobalConfig::GetSoso2ProxyPort()
{
	return m_oSoso2Config.GetCurrentProxy().GetProxyPort();
}
bool CGisMapGlobalConfig::GetSoso2CheckDataSwitch()
{
	return m_oSoso2Config.IsNeedCheckData();
}
const  std::string& CGisMapGlobalConfig::GetSoso2Url()
{
	if (m_oSoso2Config.GetUrl().empty())
	{
		return DEFAULT_SOSO2API_URL;
	}
	else
	{
		return m_oSoso2Config.GetUrl();
	}
}
const  std::string& CGisMapGlobalConfig::GetSoso2Proxy()
{
	return m_oSoso2Config.GetCurrentProxy().GetProxy();
}

uint32_t CGisMapGlobalConfig::GetBaiduTimeout()
{
	return m_oBaiduConfig.GetTimeout();
}
uint32_t CGisMapGlobalConfig::GetBaiduProxyPort()
{
	return m_oBaiduConfig.GetCurrentProxy().GetProxyPort();
}
bool CGisMapGlobalConfig::GetBaiduCheckDataSwitch()
{
	return m_oBaiduConfig.IsNeedCheckData();
}
const  std::string& CGisMapGlobalConfig::GetBaiduUrl()
{
	if (m_oBaiduConfig.GetUrl().empty())
	{
		return DEFAULT_BAIDUAPI_URL;
	}
	else
	{
		return m_oBaiduConfig.GetUrl();
	}
}
const  std::string& CGisMapGlobalConfig::GetBaiduProxy()
{
	return m_oBaiduConfig.GetCurrentProxy().GetProxy();
}
uint32_t CGisMapGlobalConfig::GetGoogleTimeout()
{
	return m_oGoogleConfig.GetTimeout();
}
uint32_t CGisMapGlobalConfig::GetGoogleProxyPort()
{
	return m_oGoogleConfig.GetCurrentProxy().GetProxyPort();
}
bool CGisMapGlobalConfig::GetGoogleCheckDataSwitch()
{
	return m_oGoogleConfig.IsNeedCheckData();
}
const  std::string& CGisMapGlobalConfig::GetGoogleUrl()
{
	if (m_oGoogleConfig.GetUrl().empty())
	{
		return DEFAULT_GOOGLEAPI_URL;
	}
	else
	{
		return m_oGoogleConfig.GetUrl();
	}
}
const  std::string& CGisMapGlobalConfig::GetGoogleProxy()
{
	return m_oGoogleConfig.GetCurrentProxy().GetProxy();
}
uint32_t CGisMapGlobalConfig::GetAliyunTimeout()
{
	return m_oAliyunConfig.GetTimeout();
}
uint32_t CGisMapGlobalConfig::GetAliyunProxyPort()
{
	return m_oAliyunConfig.GetCurrentProxy().GetProxyPort();
}
bool CGisMapGlobalConfig::GetAliyunCheckDataSwitch()
{
	return m_oAliyunConfig.IsNeedCheckData();
}
const  std::string& CGisMapGlobalConfig::GetAliyunUrl()
{
	if (m_oAliyunConfig.GetUrl().empty())
	{
		return DEFAULT_ALIYUNAPI_URL;
	}
	else
	{
		return m_oAliyunConfig.GetUrl();
	}
}
const  std::string& CGisMapGlobalConfig::GetAliyunProxy()
{
	return m_oAliyunConfig.GetCurrentProxy().GetProxy();
}

uint32_t CGisMapGlobalConfig::GetGaodeTimeout()
{
	return m_oGaodeConfig.GetTimeout();
}
uint32_t CGisMapGlobalConfig::GetGaodeProxyPort()
{
	return m_oGaodeConfig.GetCurrentProxy().GetProxyPort();
}
bool CGisMapGlobalConfig::GetGaodeCheckDataSwitch()
{
	return m_oGaodeConfig.IsNeedCheckData();
}
const  std::string& CGisMapGlobalConfig::GetGaodeUrl()
{
	if (m_oGaodeConfig.GetUrl().empty())
	{
		return DEFAULT_GAODEAPI_URL;
	}
	else
	{
		return m_oGaodeConfig.GetUrl();
	}
}
const  std::string& CGisMapGlobalConfig::GetGaodeProxy()
{
	return m_oGaodeConfig.GetCurrentProxy().GetProxy();
}
